/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package parih_threads;

/**
 *
 * @author Drak_kin
 */
public class Semaphore {
     // значение семафора
    private int counter;

    // ** пустой конструктор семафора, по умолчанию начальное значение семафора - 0
    // ** конструктор с параметром - начальным значением семафора,
    // если задано отрицательное значение, устанавливается начальное значение 0
    public Semaphore(int val) {
        if (val < 0)
            counter = 0;
        else
            counter = val;
    }

    // ** V-операция. V- и P-операции объявлены synchronized,
    // чтобы исключить одновременное выполнение их двумя или более нитями
    public synchronized void leave() {
        // возможно пробуждает нить, ожидающую у семафора
        if (counter == 0)
            this.notify();
        // увеличивает значение семафора
        counter++;
    }

    // ** P-операция
    public synchronized void enter() throws InterruptedException {
        // исключение может выбрасываться в wait
        // если значение семафора равно 0, блокирует нить
        while (counter == 0)
            this.wait();
        // уменьшает значение семафора
        counter--;
    }
}
